﻿/*
Copyright 2010 Matías Fidemraizer (www.matiasfidemraizer.com).

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

using System;
using Comkarl.Architecture.Patterns.DomainModel;

namespace Comkarl.Architecture.Patterns.MVC.Entities
{
    /// <summary>
    /// Represents a model working in a transactional context.
    /// </summary>
    /// <typeparam name="TDomainObject">
    /// The type for managed domain object.
    /// </typeparam>
    public abstract class TransactionalModel<TDomainContext, TDomainObjectIdentifierName, TDomainObject> : Model<TDomainObjectIdentifierName>, IDisposable
        where TDomainContext : DomainContext<TDomainObjectIdentifierName, TDomainObject>
        where TDomainObjectIdentifierName : IEquatable<TDomainObjectIdentifierName>
        where TDomainObject : DomainObject<TDomainObjectIdentifierName>, ICloneable
    {
        /// <summary>
        /// Default constructor.
        /// </summary>
        public TransactionalModel()
            : base(new ModelIdentifier<TDomainObjectIdentifierName>(default(TDomainObjectIdentifierName)))
        {
            context = DomainContextFactory<TDomainContext, TDomainObjectIdentifierName, TDomainObject>.CreateContext();
        }

        private readonly TDomainContext context;

        /// <summary>
        /// Gets the domain context, which is the responsible of providing transactional features.
        /// </summary>
        protected TDomainContext Context
        {
            get
            {
                return context;
            }
        }

        /// <summary>
        /// Permantly saves changes done by this model to the domain context.
        /// </summary>
        public void PersistChanges()
        {
            Context.Commit();
        }

        /// <summary>
        /// Discards all changes done by this model against the domain context.
        /// </summary>
        public void DiscardChanges()
        {
            Context.Rollback();
        }

        #region Miembros de IDisposable

        /// <summary>
        /// Releases related resources to this model. 
        /// </summary>
        public void Dispose()
        {
            Context.Dispose();
        }

        #endregion
    }
}